import os.path
import numpy as np
import itertools
import Tools
import numpy.linalg
import math
import scipy.linalg

def cartesian(*somelists):
   r=[]
   for element in itertools.product(*somelists):
       r.append(element)
   return(r)

def swaprow(a,k,j):
    tmp = np.copy(a[j,:])
    a[j,:] = np.copy(a[k,:])
    a[k,:] = tmp 
    return(a)

def swapcol(a,k,j):
    tmp = np.copy(a[:,j])
    a[:,j] = np.copy(a[:,k])
    a[:,k] = tmp 
    return(a)

def ldlt(src):
    # Algorithm 4.2.2 in Golub and Van Loan
    ma = np.copy(src)
    fullRank = True


    piv=np.zeros(len(ma),dtype=int)

    n = len(ma)

    for k in range(0,n):
        piv[k] = k
    
    for k in range(0,n):
        d=np.diagonal(ma)
        j = np.argmax(d[k:]) + k
        piv[k] = j
        
        ma = swaprow(ma,k,j)
        ma = swapcol(ma,k,j)
        
        alpha = ma[k,k]
        v = np.copy(ma[k+1:,k])

        if abs(alpha) < 1.0e-18:
            fullRank = False
            break
    
        ma[k+1:,k] = v / alpha
    
        v = v.reshape((n-k-1,1))
    
        ma[k+1:,k+1:] = ma[k+1:,k+1:] - np.matmul(v , np.transpose(v)) / alpha
    
    
    if not fullRank:
       ma[:,k:] = 0.0
       diags=(np.array(range(0,k),dtype=int),np.array(range(0,k),dtype=int))
    else:
       diags=(np.array(range(0,k+1),dtype=int),np.array(range(0,k+1),dtype=int))

    ll=np.tril(ma)
       
    ll[diags] = 1.0
    d=np.diag(np.diagonal(ma))

    return(ll,d,piv)

# Validate the Python implementation of LDLT
def valid(src,ll,d,piv):
    n = len(src)
    p=np.identity(n)
    for k in range(0,n):
        p = swaprow(p,k,piv[k])
    
    a = np.matmul(p,np.matmul(src,np.transpose(p)))
    t = np.matmul(ll,np.matmul(d,np.transpose(ll)))
    r = a - t
    r[abs(r)<1e-10]=0.0
    return(np.all(r == 0.0))

# Those patterns are used for tests and benchmarks.
# For tests, there is the need to add tests for saturation

NBA = 47
NBI = 47
NBB = 47

def randComplex(nb):
    data = np.random.randn(2*nb)
    data = Tools.normalize(data)
    data_comp = data.view(dtype=np.complex128)
    return(data_comp)

def asReal(a):
    #return(a.view(dtype=np.float64))
    return(a.reshape(np.size(a)).view(dtype=np.float64))

def writeBinaryTests(config,format):
    # For benchmarks
    NBSAMPLESA=NBA*NBI
    NBSAMPLESB=NBI*NBB

    data1=np.random.randn(NBSAMPLESA)
    data2=np.random.randn(NBSAMPLESB)
    
    data1 = Tools.normalize(data1)
    data2 = Tools.normalize(data2)

    data1C=randComplex(NBSAMPLESA)
    data2C=randComplex(NBSAMPLESB)

    config.writeInput(1, data1,"InputA")
    config.writeInput(1, data2,"InputB")


    config.writeInput(1, asReal(data1C),"InputAC")
    config.writeInput(1, asReal(data2C),"InputBC")

    # For tests
    NA=[1,2,3,4,Tools.loopnb(format,Tools.TAILONLY),
    Tools.loopnb(format,Tools.BODYONLY),
    Tools.loopnb(format,Tools.BODYANDTAIL)
    ]
    binarySizes = cartesian(NA,NA,NA)
   
    dims=[] 
    for (a,b,c) in binarySizes:
       dims.append(a)
       dims.append(b)
       dims.append(c)
    # Two matrix shapes with a common dimension
    config.writeInputS16(1, dims,"DimsBinary")

    vals=[] 
    for (a,b,c) in binarySizes:
       ma = np.copy(data1[0:a*b]).reshape(a,b)
       mb = np.copy(data2[0:b*c]).reshape(b,c)
       r = np.matmul(ma , mb) 
       r = list(r.reshape(a*c))
       vals = vals + r
    config.writeReference(1, vals,"RefMul")

   

    vals=[] 
    for (a,b,c) in binarySizes:
       ma = np.copy(data1C[0:a*b]).reshape(a,b)
       mb = np.copy(data2C[0:b*c]).reshape(b,c)
       r = np.matmul(ma , mb) 
       r = r.reshape(a*c)
       vals = vals + list(asReal(r))
    config.writeReference(1, vals,"RefCmplxMul")



def getInvertibleMatrix(d):
  m = list(np.identity(d))
  if d == 1:
    m=[[0.5]]
  if d == 2:
    c = math.cos(math.pi/4.0)  
    s = math.sin(math.pi/4.0)
    m=[[c,s],[-s,c]]
  if d == 3:
    m=[[0.804738, -0.310617, 0.505879], [0.505879, 
        0.804738, -0.310617], [-0.310617, 0.505879, 0.804738]]
  if d == 4:
    m = [[1.0, 2.0, 3.0, 4.0], [2.0, 4.0, 5.0, 6.0], 
         [3.0, 5.0, 9.0, 10.0], [4.0, 6.0, 10.0, 16.0]]
  if d == 7:
    m = [[0.978575, 0.330011, 0.951751, 0.304936, 0.924631, 0.502005, 
        0.235223], [0.185314, 0.46862, 0.955398, 0.970953, 0.637389, 
        0.619818, 0.86799], [0.380902, 0.783701, 0.865756, 0.895405, 
        0.835417, 0.85535, 0.403498], [0.641836, 0.0598755, 0.625912, 
        0.0341266, 0.0864951, 0.483158, 0.636098], [0.178972, 0.22758, 
        0.0749739, 0.379663, 0.937258, 0.834272, 0.132251], [0.314556, 
        0.456779, 0.999462, 0.904361, 0.110283, 0.380465, 0.529671], 
        [0.201637, 0.46826, 0.454319, 0.366638, 0.0510135, 0.190817,
        0.633405]]

  if d == 8:
    m = [[0.395744, 0.623798, 0.885422, 0.95415, 0.310384, 0.257541, 
        0.631426, 0.424491], [0.130945, 0.799959, 0.133693, 0.479455, 
        0.519254, 0.381039, 0.617455, 0.748273], [0.146944, 0.928945, 
        0.430936, 0.508207, 0.829023, 0.358027, 0.999501, 0.851953], 
        [0.273895, 0.685898, 0.0436612, 0.295212, 0.467651, 0.0515567, 
        0.21037, 0.607475], [0.570295, 0.281109, 0.979219, 0.0947969, 
        0.319016, 0.398405, 0.349953, 0.710002], [0.431597, 0.447659, 
        0.0747669, 0.057063, 0.165648, 0.773106, 0.135765, 0.709327], 
        [0.873836, 0.292361, 0.00202529, 0.392942, 0.520183, 0.0528055, 
        0.797982, 0.613497], [0.509682, 0.0435791, 0.780526, 0.960582, 
        0.535914, 0.216113, 0.134108, 0.225859]]

  if d == 9:
    m = [[0.755852, 0.340631, 0.605526, 0.537246, 0.143948, 0.687846, 
        0.268281, 0.386295, 0.353232], [0.609042, 0.936894, 0.181201, 
        0.645537, 0.13917, 0.652976, 0.644303, 0.662152, 0.96534], [0.509686, 
        0.92073, 0.498896, 0.55082, 0.000144712, 0.401615, 0.201727, 
        0.173404, 0.819396], [0.59557, 0.0951646, 0.808087, 0.924452, 
        0.344354, 0.407628, 0.864402, 0.343841, 0.972509], [0.808242, 
        0.716188, 0.415476, 0.776073, 0.0787058, 0.58918, 0.689208, 0.217683, 
        0.416339], [0.222844, 0.0554775, 0.243336, 0.717625, 0.0876268, 
        0.675214, 0.143021, 0.714785, 0.889134], [0.557756, 0.477962, 
        0.198405, 0.0375076, 0.979124, 0.591693, 0.312652, 0.547007, 
        0.652892], [0.131816, 0.828592, 0.0919046, 0.518972, 0.236985, 
        0.881454, 0.452603, 0.946956, 0.591222], [0.247849, 0.977108, 
        0.898247, 0.603217, 0.285739, 0.274847, 0.674735, 0.822884, 0.698022]]

  if d == 15:
     m = [[0.704168, 0.735853, 0.718608, 0.345529, 0.372926, 0.999775, 
         0.213948, 0.285632, 0.104145, 0.983514, 0.868818, 0.0910197, 
         0.608084, 0.707854, 0.487163], [0.947226, 0.673498, 0.237701, 
         0.836599, 0.231559, 0.338391, 0.953575, 0.486207, 0.564667, 0.557885, 
         0.00428352, 0.141811, 0.154465, 0.319782, 0.67351], [0.80958, 
         0.627188, 0.710782, 0.543137, 0.0174399, 0.595749, 0.198717, 
         0.960726, 0.778845, 0.638545, 0.945916, 0.252322, 0.731209, 0.107328, 
         0.253252], [0.70236, 0.530564, 0.0692471, 0.157804, 0.0108356, 
         0.00440731, 0.283927, 0.656757, 0.289001, 0.209615, 0.531473, 
         0.566135, 0.973776, 0.279332, 0.128177], [0.633133, 0.128768, 
         0.798054, 0.248072, 0.132449, 0.949232, 0.169771, 0.871594, 0.438446, 
         0.752553, 0.213159, 0.674657, 0.179118, 0.86295, 0.4113], [0.459624, 
         0.25108, 0.133495, 0.263819, 0.364067, 0.121598, 0.941177, 0.4478, 
         0.76137, 0.808942, 0.595109, 0.0158944, 0.114498, 0.133303, 
         0.0481718], [0.944067, 0.183467, 0.337882, 0.634676, 0.755476, 
         0.743938, 0.212828, 0.439745, 0.303501, 0.72898, 0.488751, 0.281193, 
         0.516431, 0.111916, 0.988385], [0.291307, 0.536322, 0.35962, 
         0.920623, 0.854874, 0.870951, 0.872989, 0.818509, 0.908277, 0.73949, 
         0.300055, 0.764275, 0.402059, 0.566754, 0.342424], [0.756966, 
         0.900864, 0.292798, 0.980525, 0.721962, 0.535073, 0.963098, 0.833779, 
         0.212301, 0.919205, 0.660289, 0.0845472, 0.451864, 0.967737, 
         0.925576], [0.916924, 0.0972206, 0.957888, 0.477663, 0.337311, 
         0.825177, 0.788022, 0.443052, 0.395918, 0.0268603, 0.609435, 
         0.316042, 0.63184, 0.1178, 0.30361], [0.178104, 0.230357, 0.406283, 
         0.145941, 0.900963, 0.609335, 0.632824, 0.188488, 0.152927, 
         0.0261378, 0.221135, 0.41915, 0.456675, 0.265506, 0.481851], 
         [0.22369, 0.581627, 0.425035, 0.33178, 0.513339, 0.708294, 0.099494, 
         0.835452, 0.0808179, 0.479402, 0.79378, 0.891339, 0.385959, 0.161006, 
         0.161274], [0.385656, 0.167598, 0.73502, 0.314725, 0.354188, 
         0.324861, 0.995976, 0.260656, 0.184682, 0.797253, 0.430961, 0.396493, 
         0.877258, 0.31995, 0.701658], [0.0635893, 0.155534, 0.835969, 
         0.254897, 0.729172, 0.926734, 0.668843, 0.202983, 0.184749, 0.670001, 
         0.923212, 0.111826, 0.0408538, 0.977616, 0.269772], [0.202834, 
         0.541264, 0.217012, 0.150064, 0.435462, 0.0353857, 0.163042, 
         0.707387, 0.0329654, 0.096392, 0.781631, 0.0813801, 0.853276, 
         0.31651, 0.233685]]
  if d == 16:
      [[0.97936, 0.498105, 0.452618, 0.299761, 0.688624, 0.247212, \
        0.228337, 0.22905, 0.563815, 0.251998, 0.5238, 0.141223, 0.0980689, \
        0.79112, 0.771182, 0.890995], [0.0256181, 0.0377277, 0.575629, \
        0.648138, 0.926218, 0.803878, 0.620333, 0.325635, 0.587355, 0.041795, \
        0.934271, 0.0690131, 0.0240136, 0.800828, 0.522999, 0.374706], \
        [0.266977, 0.208028, 0.112878, 0.0389899, 0.658311, 0.205067, \
        0.244172, 0.0762778, 0.190575, 0.677312, 0.0682093, 0.367328, \
        0.0191464, 0.988968, 0.437477, 0.130622], [0.907823, 0.0116559, \
        0.614526, 0.447443, 0.0126975, 0.995496, 0.947676, 0.659996, \
        0.321547, 0.725415, 0.658426, 0.0243924, 0.0843519, 0.351748, \
        0.974332, 0.673381], [0.375012, 0.719626, 0.721219, 0.766905, \
        0.17065, 0.648905, 0.770983, 0.360008, 0.344226, 0.179633, 0.347905, \
        0.555561, 0.742615, 0.908389, 0.806959, 0.176078], [0.872167, \
        0.321839, 0.098607, 0.954515, 0.627286, 0.235082, 0.746179, 0.163606, \
        0.899323, 0.871471, 0.712448, 0.956971, 0.736687, 0.750702, 0.843348, \
        0.302435], [0.444862, 0.0644597, 0.765519, 0.518397, 0.765541, \
        0.900375, 0.201853, 0.490325, 0.721786, 0.893647, 0.774724, \
        0.0983631, 0.339887, 0.526084, 0.0786152, 0.515697], [0.438801, \
        0.226628, 0.125093, 0.886642, 0.617766, 0.71696, 0.473172, 0.640949, \
        0.67688, 0.676214, 0.453662, 0.345796, 0.608999, 0.904448, 0.0965741, \
        0.00461771], [0.467399, 0.292235, 0.0418646, 0.116632, 0.0766192, \
        0.269051, 0.411649, 0.0538381, 0.973959, 0.667106, 0.301662, \
        0.977206, 0.891751, 0.420267, 0.441334, 0.0896179], [0.249969, \
        0.672614, 0.623966, 0.609733, 0.320772, 0.39723, 0.845196, 0.653877, \
        0.0599186, 0.340188, 0.199787, 0.598104, 0.45664, 0.920485, 0.969439, \
        0.446555], [0.0932837, 0.0247635, 0.747644, 0.438759, 0.639154, \
        0.754049, 0.379433, 0.968655, 0.0452146, 0.208123, 0.252654, \
        0.261898, 0.608665, 0.145211, 0.395368, 0.799111], [0.697823, \
        0.382906, 0.456515, 0.262579, 0.284169, 0.881488, 0.860877, 0.155548, \
        0.537387, 0.804235, 0.311383, 0.183216, 0.677692, 0.829542, 0.406049, \
        0.860392], [0.467668, 0.385633, 0.654692, 0.841125, 0.178406, \
        0.668945, 0.369609, 0.809711, 0.454593, 0.632028, 0.605791, 0.643851, \
        0.787023, 0.285633, 0.832216, 0.30892], [0.303559, 0.704898, 0.61118, \
        0.435547, 0.173678, 0.788689, 0.319511, 0.648378, 0.635417, 0.125127, \
        0.310251, 0.800819, 0.4863, 0.924361, 0.308059, 0.952175], [0.449844, \
        0.215496, 0.257826, 0.556383, 0.259735, 0.197234, 0.0509903, 0.21474, \
        0.145085, 0.41288, 0.876758, 0.096721, 0.228955, 0.0152248, 0.126501, \
        0.28899], [0.336668, 0.580015, 0.932761, 0.989783, 0.667379, \
        0.798751, 0.587173, 0.445902, 0.041448, 0.311878, 0.0332857, \
        0.401984, 0.795049, 0.8222, 0.678648, 0.807558]]
  if d == 17:
    m = [[0.133335, 0.517058, 0.701105, 0.306717, 0.0991376, 0.00531119, \
          0.958215, 0.703452, 0.109332, 0.117755, 0.163908, 0.305222, 0.595706, \
          0.712064, 0.889725, 0.405096, 0.0855293], [0.77937, 0.764142, \
          0.230949, 0.102371, 0.192378, 0.407009, 0.677376, 0.520533, 0.811622, \
          0.982079, 0.418158, 0.242076, 0.273134, 0.366346, 0.615423, 0.767038, \
          0.388856], [0.657456, 0.769374, 0.111209, 0.832816, 0.636625, \
          0.00292606, 0.457253, 0.227427, 0.146904, 0.237357, 0.391302, 0.2303, \
          0.937593, 0.144985, 0.328774, 0.36934, 0.51035], [0.983251, 0.279937, \
          0.844802, 0.903298, 0.348192, 0.156749, 0.489659, 0.889335, 0.615883, \
          0.66777, 0.997259, 0.262593, 0.481978, 0.969208, 0.0267358, 0.190169, \
          0.510358], [0.386987, 0.176313, 0.605099, 0.612098, 0.479341, \
          0.148345, 0.596891, 0.339071, 0.656778, 0.353512, 0.479927, 0.742252, \
          0.570376, 0.722239, 0.637817, 0.0266415, 0.323902], [0.0382872, \
          0.711866, 0.424079, 0.789902, 0.59981, 0.598953, 0.463945, 0.631132, \
          0.434764, 0.749596, 0.255799, 0.0869052, 0.806549, 0.906938, \
          0.583024, 0.728984, 0.110368], [0.783597, 0.747879, 0.735447, \
          0.695983, 0.204768, 0.109041, 0.552302, 0.66833, 0.829247, 0.0531204, \
          0.247598, 0.994937, 0.807362, 0.719985, 0.234183, 0.566978, \
          0.327766], [0.983224, 0.90949, 0.276237, 0.534742, 0.681737, \
          0.652466, 0.848426, 0.769707, 0.13917, 0.784081, 0.966263, 0.492853, \
          0.177233, 0.411634, 0.620385, 0.344837, 0.877829], [0.230241, \
          0.732502, 0.626417, 0.369864, 0.411434, 0.00231683, 0.164025, \
          0.899565, 0.602661, 0.917313, 0.96369, 0.749923, 0.174551, 0.738964, \
          0.240355, 0.302181, 0.731165], [0.492266, 0.367882, 0.475643, \
          0.938073, 0.57225, 0.570115, 0.392919, 0.440847, 0.889683, 0.0749963, \
          0.820675, 0.0673754, 0.208015, 0.208484, 0.0223897, 0.388032, \
          0.105848], [0.498337, 0.204332, 0.935046, 0.71546, 0.0461249, \
          0.636579, 0.904695, 0.857191, 0.304475, 0.0944178, 0.272618, \
          0.598437, 0.504778, 0.00254614, 0.0227495, 0.883251, 0.819557], \
          [0.917979, 0.0625552, 0.84745, 0.339056, 0.19506, 0.606289, 0.958305, \
          0.138779, 0.275338, 0.367648, 0.806884, 0.648595, 0.847197, 0.357685, \
          0.162295, 0.962875, 0.0274199], [0.031272, 0.68129, 0.191706, \
          0.376588, 0.077411, 0.786152, 0.528892, 0.168522, 0.496011, \
          0.0528135, 0.229117, 0.232179, 0.64569, 0.0493392, 0.594895, \
          0.195047, 0.466139], [0.0846469, 0.680764, 0.320802, 0.153364, \
          0.877709, 0.880937, 0.721778, 0.940679, 0.687212, 0.131609, 0.587884, \
          0.699248, 0.272942, 0.526976, 0.303268, 0.545032, 0.915477], \
          [0.00113185, 0.273766, 0.645106, 0.915763, 0.362201, 0.970536, \
          0.853713, 0.0807933, 0.496775, 0.74697, 0.361887, 0.93802, 0.123652, \
          0.313722, 0.654343, 0.237378, 0.725082], [0.423648, 0.361588, \
          0.108125, 0.167796, 0.945988, 0.686343, 0.94361, 0.501885, 0.952198, \
          0.785797, 0.727547, 0.100525, 0.0696632, 0.0342614, 0.0566811, \
          0.0697371, 0.250538], [0.397104, 0.415814, 0.298294, 0.385464, \
          0.3696, 0.596503, 0.651478, 0.512156, 0.0903898, 0.824847, 0.856181, \
          0.758707, 0.723593, 0.897521, 0.489231, 0.552946, 0.435435]]
  if d == 32:
     m = [[0.00486175, 0.671512, 0.671229, 0.603438, 0.509858, 0.635903, \
           0.672983, 0.96238, 0.501158, 0.0766142, 0.378993, 0.128323, 0.979438, \
           0.848874, 0.746088, 0.182961, 0.295819, 0.599062, 0.0564427, \
           0.877226, 0.158201, 0.310007, 0.255376, 0.61497, 0.0439793, 0.211115, \
           0.60649, 0.539429, 0.601855, 0.459125, 0.130523, 0.00523878], \
           [0.337683, 0.00592341, 0.0341371, 0.00544369, 0.512848, 0.245626, \
           0.115845, 0.679194, 0.479485, 0.760685, 0.251599, 0.0456632, \
           0.423679, 0.79359, 0.278378, 0.875334, 0.413503, 0.211325, 0.408999, \
           0.729473, 0.323137, 0.81086, 0.0880499, 0.854478, 0.0673655, \
           0.961338, 0.560391, 0.112047, 0.709918, 0.375023, 0.136046, \
           0.744921], [0.638824, 0.807032, 0.368559, 0.437475, 0.391191, \
           0.487815, 0.294866, 0.948817, 0.0402009, 0.324887, 0.620699, \
           0.0677868, 0.630819, 0.587703, 0.923385, 0.393539, 0.450501, \
           0.579254, 0.0229916, 0.251207, 0.276373, 0.583127, 0.884949, \
           0.134654, 0.597067, 0.968417, 0.771328, 0.76235, 0.966834, 0.832444, \
           0.463516, 0.985571], [0.91913, 0.285539, 0.494593, 0.141851, \
           0.429374, 0.279873, 0.0602374, 0.241835, 0.120068, 0.517207, 0.77467, \
           0.148957, 0.311078, 0.638281, 0.754867, 0.919708, 0.865302, \
           0.0919983, 0.99489, 0.477339, 0.561301, 0.19076, 0.875394, 0.665173, \
           0.257375, 0.737282, 0.484776, 0.416522, 0.746236, 0.899974, 0.164366, \
           0.221188], [0.83354, 0.393181, 0.317211, 0.278821, 0.116465, \
           0.305508, 0.235513, 0.073043, 0.825076, 0.56938, 0.551798, 0.179343, \
           0.95083, 0.647773, 0.901178, 0.176792, 0.254499, 0.188447, 0.634042, \
           0.320702, 0.324266, 0.341313, 0.66288, 0.374912, 0.144847, 0.143202, \
           0.652035, 0.0252101, 0.0852716, 0.126889, 0.877229, 0.718062], \
           [0.413352, 0.129036, 0.104131, 0.698749, 0.0523534, 0.58054, 0.8425, \
           0.748314, 0.458127, 0.716553, 0.848332, 0.210169, 0.577707, \
           0.0823855, 0.0824533, 0.524593, 0.563235, 0.534768, 0.545148, \
           0.494946, 0.329187, 0.581969, 0.515833, 0.746702, 0.969672, 0.480806, \
           0.847425, 0.61117, 0.305932, 0.463121, 0.879455, 0.945384], \
           [0.822641, 0.593828, 0.278183, 0.332009, 0.0341548, 0.324217, \
           0.0218753, 0.436835, 0.618974, 0.772488, 0.674042, 0.484553, \
           0.0966171, 0.983133, 0.160891, 0.813557, 0.635934, 0.585081, \
           0.242585, 0.376284, 0.694645, 0.955019, 0.960159, 0.589983, 0.687797, \
           0.308842, 0.308321, 0.324241, 0.640412, 0.465652, 0.580236, \
           0.933036], [0.515264, 0.770184, 0.0536107, 0.776898, 0.642594, \
           0.195816, 0.671027, 0.43862, 0.446784, 0.306716, 0.915457, 0.149282, \
           0.668602, 0.42236, 0.470068, 0.170464, 0.637024, 0.917844, 0.567187, \
           0.0532555, 0.770735, 0.190391, 0.205231, 0.031518, 0.642223, \
           0.016357, 0.692619, 0.0832153, 0.0436543, 0.0906243, 0.661425, \
           0.0891193], [0.466054, 0.900667, 0.744557, 0.328932, 0.60276, 0.7779, \
           0.786752, 0.436824, 0.842516, 0.611117, 0.480837, 0.1921, 0.0116031, \
           0.890494, 0.061645, 0.386379, 0.469331, 0.0273887, 0.732736, \
           0.485862, 0.374499, 0.533253, 0.283584, 0.759343, 0.126319, 0.993569, \
           0.103128, 0.33436, 0.0411333, 0.395071, 0.225115, 0.969658], \
           [0.468083, 0.289069, 0.637141, 0.310331, 0.677455, 0.0455287, \
           0.260893, 0.32699, 0.0778317, 0.0824527, 0.903272, 0.487342, \
           0.706676, 0.362973, 0.0680058, 0.828021, 0.239359, 0.636767, \
           0.913178, 0.282053, 0.258906, 0.0337252, 0.605338, 0.95831, 0.845272, \
           0.0103118, 0.247598, 0.886535, 0.10445, 0.536929, 0.98549, 0.183116], \
           [0.545992, 0.652514, 0.753503, 0.842167, 0.0110663, 0.713291, \
           0.375889, 0.803058, 0.535099, 0.810246, 0.544022, 0.281562, 0.134866, \
           0.967045, 0.332599, 0.936183, 0.0973818, 0.838902, 0.0228137, \
           0.49566, 0.670023, 0.0553362, 0.0187522, 0.468683, 0.402021, \
           0.912399, 0.239761, 0.56295, 0.647782, 0.77263, 0.381246, 0.6888], \
           [0.640077, 0.07539, 0.16995, 0.290403, 0.496647, 0.3411, 0.719986, \
           0.112845, 0.478323, 0.0522038, 0.792506, 0.623008, 0.837196, \
           0.269674, 0.308898, 0.518689, 0.16468, 0.28711, 0.408763, 0.0674661, \
           0.506758, 0.0807132, 0.382719, 0.192486, 0.868124, 0.68044, 0.947733, \
           0.721963, 0.964378, 0.709648, 0.802888, 0.314101], [0.383112, \
           0.591224, 0.593851, 0.242117, 0.682389, 0.485626, 0.567901, 0.345966, \
           0.941318, 0.233239, 0.646387, 0.736894, 0.52425, 0.850128, 0.224221, \
           0.22348, 0.758234, 0.178456, 0.121915, 0.688154, 0.892199, 0.363851, \
           0.215289, 0.178046, 0.291059, 0.757939, 0.579081, 0.441422, 0.784167, \
           0.00238388, 0.529623, 0.559091], [0.118876, 0.406047, 0.611397, \
           0.569115, 0.019261, 0.418224, 0.778077, 0.885718, 0.857737, 0.391441, \
           0.069531, 0.971273, 0.558379, 0.353897, 0.454349, 0.85623, 0.798987, \
           0.327323, 0.413279, 0.882087, 0.977398, 0.944955, 0.269674, \
           0.00938203, 0.765171, 0.813286, 0.47253, 0.135663, 0.758958, \
           0.144282, 0.776811, 0.0878017], [0.729824, 0.107338, 0.379056, \
           0.251152, 0.552293, 0.223821, 0.286129, 0.846771, 0.0799255, \
           0.334347, 0.32592, 0.69965, 0.133489, 0.531975, 0.719641, 0.184999, \
           0.164666, 0.773531, 0.365731, 0.243699, 0.752994, 0.78749, 0.241201, \
           0.241564, 0.806296, 0.109006, 0.13062, 0.205934, 0.816858, 0.0382181, \
           0.889981, 0.519696], [0.378298, 0.0332494, 0.107644, 0.822036, \
           0.976829, 0.865426, 0.340094, 0.963092, 0.192734, 0.26829, 0.726501, \
           0.348085, 0.144679, 0.406277, 0.26813, 0.285053, 0.64562, 0.811063, \
           0.803126, 0.5953, 0.825069, 0.636111, 0.708634, 0.19095, 0.255352, \
           0.356187, 0.42446, 0.4196, 0.874136, 0.711788, 0.27029, 0.318715], \
           [0.789545, 0.121632, 0.490996, 0.623702, 0.0566727, 0.558638, \
           0.207153, 0.959089, 0.917647, 0.210203, 0.336343, 0.282568, 0.839655, \
           0.749362, 0.4425, 0.968553, 0.887713, 0.792622, 0.625122, 0.864763, \
           0.0329625, 0.52034, 0.329579, 0.00394267, 0.0298472, 0.678188, \
           0.576767, 0.51385, 0.798511, 0.637733, 0.260121, 0.912177], \
           [0.736239, 0.209724, 0.924144, 0.0489936, 0.325291, 0.657606, \
           0.190817, 0.932395, 0.360709, 0.168952, 0.214184, 0.849683, 0.259534, \
           0.207044, 0.216733, 0.484543, 0.405837, 0.427172, 0.123429, 0.875985, \
           0.933807, 0.326904, 0.408833, 0.231656, 0.814313, 0.820576, 0.501717, \
           0.0878438, 0.498665, 0.105059, 0.0962973, 0.364031], [0.0235064, \
           0.00758757, 0.538598, 0.98839, 0.324052, 0.316089, 0.176858, \
           0.173556, 0.800775, 0.87829, 0.392057, 0.941723, 0.57049, 0.991474, \
           0.334767, 0.950152, 0.283758, 0.00659644, 0.37855, 0.38408, 0.803609, \
           0.662623, 0.739661, 0.318444, 0.544472, 0.482995, 0.80555, 0.0455931, \
           0.0423814, 0.173049, 0.150615, 0.98448], [0.0947985, 0.809412, \
           0.865235, 0.100868, 0.650863, 0.4445, 0.580767, 0.83095, 0.597687, \
           0.218641, 0.677191, 0.669111, 0.625174, 0.822944, 0.538428, 0.347098, \
           0.212809, 0.524027, 0.752455, 0.416554, 0.699941, 0.860133, 0.564371, \
           0.655896, 0.897347, 0.0766369, 0.746071, 0.477173, 0.668873, \
           0.996869, 0.443135, 0.041959], [0.375554, 0.440842, 0.460433, \
           0.786897, 0.0264724, 0.0250899, 0.815844, 0.0471153, 0.263669, \
           0.0169742, 0.497879, 0.217152, 0.19403, 0.0779415, 0.0675226, \
           0.344732, 0.249825, 0.569485, 0.123544, 0.140785, 0.257697, 0.992708, \
           0.964825, 0.684051, 0.349104, 0.302872, 0.6903, 0.52081, 0.153346, \
           0.751101, 0.4333, 0.692784], [0.413996, 0.668545, 0.80703, 0.182556, \
           0.0134766, 0.111083, 0.0541739, 0.905122, 0.768152, 0.216453, \
           0.433161, 0.98665, 0.84733, 0.777085, 0.452531, 0.37719, 0.976604, \
           0.750674, 0.997839, 0.458785, 0.411489, 0.251714, 0.799549, 0.454091, \
           0.32992, 0.143513, 0.167756, 0.0225491, 0.756232, 0.257239, \
           0.0451669, 0.340243], [0.974505, 0.798027, 0.973791, 0.537498, \
           0.300131, 0.83449, 0.140613, 0.909839, 0.172297, 0.0527656, 0.764177, \
           0.348042, 0.285017, 0.713485, 0.149116, 0.000701093, 0.454292, \
           0.313439, 0.354333, 0.0799855, 0.447158, 0.44342, 0.243024, 0.105926, \
           0.142257, 0.349596, 0.636754, 0.571759, 0.50944, 0.486054, 0.770275, \
           0.173402], [0.821058, 0.587962, 0.300433, 0.710537, 0.500014, \
           0.12987, 0.523508, 0.441253, 0.567836, 0.677178, 0.913873, 0.483632, \
           0.670528, 0.771258, 0.297251, 0.734813, 0.697905, 0.875179, 0.664255, \
           0.548498, 0.266549, 0.621289, 0.862001, 0.981694, 0.530604, 0.402943, \
           0.039312, 0.0585467, 0.232252, 0.427328, 0.306247, 0.0586208], \
           [0.747795, 0.690828, 0.00217213, 0.321873, 0.806692, 0.405953, \
           0.592753, 0.145827, 0.435068, 0.74242, 0.905952, 0.893161, 0.112491, \
           0.821869, 0.556659, 0.479933, 0.474456, 0.779092, 0.470226, 0.570959, \
           0.488268, 0.937245, 0.96444, 0.000240915, 0.727272, 0.944077, \
           0.902209, 0.47192, 0.576518, 0.294185, 0.45726, 0.998216], [0.565336, \
           0.904815, 0.0974912, 0.318141, 0.14708, 0.510372, 0.241564, 0.325932, \
           0.748063, 0.820055, 0.742096, 0.875849, 0.84732, 0.903475, 0.459597, \
           0.369881, 0.997251, 0.574695, 0.327148, 0.963399, 0.222865, 0.015163, \
           0.988431, 0.252985, 0.660087, 0.824832, 0.558565, 0.0432452, \
           0.212922, 0.112049, 0.15882, 0.876257], [0.915658, 0.7995, 0.887197, \
           0.547283, 0.68251, 0.0875499, 0.842114, 0.834181, 0.569782, \
           0.0906641, 0.722069, 0.462267, 0.529126, 0.470145, 0.49426, 0.122644, \
           0.115869, 0.27918, 0.71576, 0.677887, 0.946562, 0.458445, 0.239908, \
           0.420514, 0.483277, 0.710438, 0.182457, 0.095803, 0.502548, \
           0.0847858, 0.27578, 0.688578], [0.764824, 0.656358, 0.475478, \
           0.053971, 0.393609, 0.555448, 0.807086, 0.0845441, 0.111597, \
           0.386532, 0.625653, 0.375229, 0.504558, 0.403603, 0.51777, 0.465392, \
           0.46007, 0.969979, 0.256666, 0.0914928, 0.495148, 0.496291, 0.955921, \
           0.784861, 0.353375, 0.476911, 0.435112, 0.180558, 0.121669, 0.404513, \
           0.655334, 0.154492], [0.109089, 0.98058, 0.0043154, 0.430207, \
           0.53258, 0.638813, 0.129111, 0.707437, 0.107928, 0.562803, 0.446195, \
           0.546008, 0.363152, 0.195992, 0.251653, 0.215657, 0.962838, 0.890721, \
           0.394591, 0.435407, 0.502739, 0.47562, 0.143479, 0.343967, 0.223496, \
           0.813379, 0.441616, 0.895008, 0.835599, 0.78915, 0.916829, 0.197724], \
           [0.364765, 0.260923, 0.907561, 0.219673, 0.465021, 0.212777, \
           0.161095, 0.118085, 0.371207, 0.915132, 0.798451, 0.197264, 0.216205, \
           0.834418, 0.480233, 0.0619294, 0.216872, 0.423901, 0.73477, 0.557181, \
           0.874451, 0.682996, 0.447527, 0.249879, 0.516152, 0.219925, 0.734962, \
           0.311518, 0.713282, 0.189919, 0.953687, 0.878328], [0.608323, \
           0.286353, 0.292643, 0.586521, 0.652889, 0.522976, 0.606721, 0.549773, \
           0.721642, 0.117941, 0.69444, 0.115633, 0.135029, 0.311762, 0.36826, \
           0.183629, 0.685729, 0.808256, 0.804516, 0.367428, 0.248443, 0.950368, \
           0.592981, 0.464375, 0.0405165, 0.439708, 0.425667, 0.12509, 0.191941, \
           0.585167, 0.501442, 0.758111], [0.51859, 0.318801, 0.0511754, \
           0.528103, 0.696379, 0.163925, 0.923365, 0.889314, 0.803733, 0.657009, \
           0.162188, 0.572416, 0.414081, 0.67728, 0.842954, 0.519273, 0.169699, \
           0.408016, 0.86035, 0.233082, 0.0787194, 0.842804, 0.98437, 0.784041, \
           0.413102, 0.891386, 0.322925, 0.545048, 0.392852, 0.226103, 0.969887, \
           0.548364]]
  if d == 33:
    m = [[0.180472, 0.342639, 0.325276, 0.545704, 0.451983, 0.373818, \
          0.78615, 0.255714, 0.838041, 0.097278, 0.622356, 0.89102, 0.5914, \
          0.889809, 0.310819, 0.474241, 0.630476, 0.338754, 0.39599, 0.557622, \
          0.0223869, 0.508037, 0.90211, 0.391692, 0.340507, 0.421016, 0.598469, \
          0.264287, 0.797811, 0.955201, 0.977077, 0.296768, 0.00568295], \
          [0.0402768, 0.733473, 0.147792, 0.62644, 0.673563, 0.3327, 0.208436, \
          0.50946, 0.123825, 0.971975, 0.243086, 0.855794, 0.202858, 0.404454, \
          0.833336, 0.638796, 0.961742, 0.391732, 0.409352, 0.459476, 0.763147, \
          0.952704, 0.870003, 0.324707, 0.0190341, 0.976663, 0.933853, \
          0.797752, 0.947691, 0.173108, 0.679321, 0.0148456, 0.797354], \
          [0.40818, 0.819997, 0.158828, 0.507639, 0.822462, 0.263336, 0.678454, \
          0.145643, 0.0160026, 0.418995, 0.342777, 0.848048, 0.0583393, \
          0.809739, 0.432244, 0.578278, 0.771404, 0.105054, 0.344225, 0.199467, \
          0.818476, 0.102374, 0.589968, 0.511945, 0.494632, 0.0415236, \
          0.521946, 0.478924, 0.845236, 0.796915, 0.0514031, 0.550806, \
          0.0886831], [0.0739224, 0.590408, 0.642615, 0.185089, 0.033212, \
          0.0184966, 0.361786, 0.403862, 0.0620605, 0.546202, 0.428819, \
          0.55923, 0.578064, 0.208484, 0.523704, 0.188812, 0.970661, 0.269089, \
          0.704783, 0.288323, 0.853953, 0.579124, 0.369026, 0.636393, 0.267555, \
          0.406682, 0.208, 0.0433634, 0.793517, 0.92274, 0.289819, 0.398678, \
          0.625487], [0.569808, 0.411696, 0.367159, 0.796069, 0.242911, \
          0.52369, 0.0414615, 0.375769, 0.0349582, 0.0468055, 0.523025, \
          0.44659, 0.692033, 0.757768, 0.164422, 0.981635, 0.182349, 0.190806, \
          0.625824, 0.843379, 0.875716, 0.36376, 0.793023, 0.454705, 0.689926, \
          0.262633, 0.387627, 0.217524, 0.0113575, 0.265817, 0.427361, \
          0.549389, 0.316787], [0.459613, 0.638459, 0.0575594, 0.520666, \
          0.853265, 0.0741818, 0.644304, 0.241368, 0.00389035, 0.126602, \
          0.608203, 0.750404, 0.136667, 0.489259, 0.645017, 0.931951, 0.597064, \
          0.502011, 0.679183, 0.745949, 0.75322, 0.0052193, 0.871952, 0.402392, \
          0.724891, 0.344997, 0.596444, 0.756673, 0.0998223, 0.968595, \
          0.605174, 0.532889, 0.653592], [0.11938, 0.283165, 0.254346, \
          0.781306, 0.148391, 0.924732, 0.64329, 0.48335, 0.444858, 0.508379, \
          0.380283, 0.793816, 0.342015, 0.445115, 0.508993, 0.041112, \
          0.0718632, 0.412107, 0.263165, 0.670939, 0.737432, 0.777792, 0.53989, \
          0.336085, 0.962137, 0.322577, 0.326377, 0.571092, 0.686163, \
          0.000445441, 0.575301, 0.574112, 0.0713595], [0.182552, 0.951371, \
          0.083816, 0.502208, 0.178327, 0.836613, 0.597658, 0.697877, 0.432917, \
          0.923784, 0.127485, 0.880965, 0.971141, 0.139048, 0.204491, 0.517381, \
          0.558202, 0.470632, 0.994191, 0.884601, 0.494413, 0.606673, \
          0.0941226, 0.856249, 0.745468, 0.661075, 0.186202, 0.800699, \
          0.545882, 0.78278, 0.164325, 0.56654, 0.234361], [0.452066, 0.556187, \
          0.404928, 0.81359, 0.604885, 0.812544, 0.105253, 0.49513, 0.623892, \
          0.406024, 0.563282, 0.423169, 0.917038, 0.629291, 0.354677, 0.637767, \
          0.0126974, 0.403746, 0.271005, 0.0239397, 0.741324, 0.000759967, \
          0.0278572, 0.850122, 0.622846, 0.306142, 0.308556, 0.247874, \
          0.773088, 0.164618, 0.793543, 0.553657, 0.737617], [0.191243, \
          0.888204, 0.0649631, 0.0835789, 0.319853, 0.0282413, 0.82888, \
          0.623575, 0.350648, 0.329508, 0.750929, 0.981378, 0.744727, 0.161868, \
          0.0144347, 0.559983, 0.269144, 0.668579, 0.288788, 0.753556, \
          0.844752, 0.773795, 0.269356, 0.0521382, 0.594657, 0.586715, \
          0.412627, 0.735924, 0.994949, 0.597759, 0.780839, 0.981428, \
          0.886983], [0.500082, 0.633381, 0.840406, 0.797838, 0.400964, \
          0.527165, 0.126518, 0.851037, 0.0464741, 0.193829, 0.706508, 0.19069, \
          0.525847, 0.720792, 0.511571, 0.970815, 0.411656, 0.345454, 0.914402, \
          0.985735, 0.0882571, 0.472655, 0.288508, 0.648997, 0.960146, \
          0.345016, 0.234769, 0.681618, 0.122471, 0.587405, 0.149163, 0.766955, \
          0.205045], [0.499167, 0.71925, 0.521849, 0.830513, 0.199306, \
          0.843249, 0.676695, 0.970858, 0.63353, 0.574783, 0.779931, 0.598516, \
          0.82729, 0.295628, 0.62557, 0.0100106, 0.00171756, 0.294511, \
          0.474362, 0.729168, 0.433305, 0.175542, 0.750116, 0.283787, 0.441664, \
          0.546287, 0.48493, 0.324103, 0.686833, 0.146713, 0.630067, 0.188277, \
          0.181819], [0.478044, 0.0244674, 0.400708, 0.417688, 0.682018, \
          0.160381, 0.963503, 0.988708, 0.867003, 0.654303, 0.432825, 0.739039, \
          0.461256, 0.560147, 0.764569, 0.422231, 0.682743, 0.54797, 0.632032, \
          0.790543, 0.54767, 0.784373, 0.333022, 0.581093, 0.755827, 0.699565, \
          0.578381, 0.836268, 0.708734, 0.920027, 0.596686, 0.330069, 0.74928], \
          [0.526921, 0.642604, 0.172258, 0.505533, 0.234636, 0.517936, \
          0.915639, 0.12547, 0.481349, 0.217246, 0.903549, 0.277123, 0.617767, \
          0.999133, 0.736606, 0.653349, 0.135948, 0.046346, 0.647411, 0.889216, \
          0.0830548, 0.140618, 0.0429108, 0.0574949, 0.530104, 0.44246, \
          0.0710688, 0.365357, 0.323366, 0.299136, 0.301513, 0.521108, \
          0.396917], [0.538949, 0.0597017, 0.0426872, 0.77976, 0.638647, \
          0.834551, 0.297674, 0.453674, 0.134076, 0.891232, 0.494914, 0.657503, \
          0.20045, 0.417682, 0.699186, 0.723612, 0.716046, 0.908808, 0.325256, \
          0.267951, 0.877024, 0.547235, 0.734905, 0.707428, 0.22615, 0.170641, \
          0.251801, 0.372346, 0.45977, 0.99796, 0.611535, 0.532378, 0.506652], \
          [0.855429, 0.224705, 0.406208, 0.304333, 0.66549, 0.271182, 0.294317, \
          0.695005, 0.42295, 0.350388, 0.909051, 0.337894, 0.115478, 0.573011, \
          0.00885253, 0.511718, 0.408663, 0.45689, 0.932546, 0.392435, \
          0.557556, 0.21016, 0.332412, 0.981314, 0.0808182, 0.766876, 0.943551, \
          0.199142, 0.944077, 0.6711, 0.44381, 0.671061, 0.962204], [0.0849663, \
          0.396795, 0.693205, 0.232572, 0.891823, 0.390317, 0.0506422, \
          0.743269, 0.902357, 0.64524, 0.232391, 0.538827, 0.33895, 0.298695, \
          0.14703, 0.0636232, 0.735462, 0.026976, 0.533921, 0.50922, 0.088565, \
          0.112848, 0.171562, 0.956842, 0.798053, 0.481693, 0.537116, \
          0.00319687, 0.784561, 0.150593, 0.866739, 0.748044, 0.339033], \
          [0.811655, 0.228755, 0.143346, 0.863177, 0.677884, 0.0130702, \
          0.417937, 0.829027, 0.396751, 0.968414, 0.094855, 0.382097, 0.53666, \
          0.194071, 0.878117, 0.321591, 0.677877, 0.350024, 0.0109106, \
          0.0429985, 0.482836, 0.972063, 0.378966, 0.575559, 0.859691, \
          0.351807, 0.0302582, 0.922712, 0.502291, 0.362365, 0.193774, \
          0.638772, 0.00484069], [0.0419704, 0.948873, 0.00938601, 0.0589582, \
          0.222804, 0.225482, 0.839349, 0.842982, 0.606636, 0.886988, 0.460524, \
          0.55637, 0.833036, 0.896245, 0.128409, 0.69833, 0.200041, 0.812714, \
          0.338841, 0.0418833, 0.332366, 0.552208, 0.872062, 0.77003, 0.460792, \
          0.487551, 0.590676, 0.715252, 0.159437, 0.245553, 0.44435, 0.304755, \
          0.332684], [0.28418, 0.20182, 0.102562, 0.575487, 0.725905, 0.734821, \
          0.145425, 0.20771, 0.247928, 0.455078, 0.151963, 0.863549, 0.391113, \
          0.107591, 0.397905, 0.203068, 0.982776, 0.0648292, 0.286489, 0.24354, \
          0.774618, 0.553899, 0.398329, 0.706091, 0.78104, 0.617354, 0.306895, \
          0.880162, 0.891409, 0.686051, 0.992439, 0.678662, 0.715439], \
          [0.580313, 0.557155, 0.0863804, 0.87926, 0.916673, 0.320722, \
          0.435677, 0.919475, 0.125682, 0.0551085, 0.508548, 0.23035, 0.181977, \
          0.541161, 0.074376, 0.114519, 0.307677, 0.482986, 0.796034, 0.367716, \
          0.685904, 0.852248, 0.291913, 0.00395931, 0.980518, 0.673355, \
          0.828038, 0.18139, 0.658491, 0.335332, 0.347627, 0.30871, 0.505173], \
          [0.0823304, 0.689252, 0.733335, 0.384638, 0.872219, 0.751718, \
          0.14283, 0.964649, 0.685294, 0.81242, 0.379802, 0.637524, 0.108016, \
          0.204059, 0.986508, 0.644499, 0.270986, 0.327306, 0.46137, 0.368802, \
          0.265613, 0.253858, 0.0469391, 0.489631, 0.00621, 0.432485, 0.352592, \
          0.620197, 0.0221417, 0.0961601, 0.0174084, 0.542534, 0.785859], \
          [0.834294, 0.311568, 0.0635048, 0.698034, 0.424823, 0.699808, \
          0.100361, 0.711107, 0.372018, 0.47525, 0.0516863, 0.345562, 0.367445, \
          0.39923, 0.352465, 0.925622, 0.0800203, 0.621117, 0.213941, 0.796669, \
          0.242094, 0.0775034, 0.180726, 0.792237, 0.499691, 0.539115, \
          0.606528, 0.2737, 0.191404, 0.204545, 0.662633, 0.958458, 0.870762], \
          [0.0346136, 0.108385, 0.804346, 0.0611441, 0.926934, 0.399432, \
          0.180015, 0.584645, 0.884758, 0.846218, 0.255149, 0.717863, 0.70456, \
          0.354724, 0.454721, 0.69625, 0.55816, 0.556823, 0.453642, 0.8659, \
          0.183238, 0.117989, 0.0827856, 0.584917, 0.389932, 0.501786, 0.69244, \
          0.455006, 0.839933, 0.483699, 0.965653, 0.690272, 0.378605], \
          [0.649339, 0.459381, 0.707958, 0.347764, 0.234653, 0.355172, 0.92703, \
          0.0272606, 0.835834, 0.626404, 0.852447, 0.84299, 0.613014, 0.374245, \
          0.410823, 0.821113, 0.544167, 0.19295, 0.222633, 0.646794, 0.880685, \
          0.326803, 0.111279, 0.922648, 0.230494, 0.575541, 0.91982, 0.014955, \
          0.782726, 0.187276, 0.593701, 0.976028, 0.694473], [0.66811, \
          0.689909, 0.299129, 0.348343, 0.34427, 0.0159964, 0.532865, 0.307591, \
          0.149309, 0.14992, 0.710193, 0.72558, 0.359774, 0.494283, 0.890411, \
          0.870821, 0.665459, 0.709639, 0.530634, 0.679075, 0.636084, 0.977629, \
          0.743466, 0.518235, 0.75635, 0.469916, 0.702219, 0.487181, 0.232738, \
          0.0337613, 0.126202, 0.741976, 0.556195], [0.0391251, 0.898173, \
          0.851775, 0.85659, 0.647724, 0.0637494, 0.143015, 0.209207, 0.624062, \
          0.463522, 0.609943, 0.998072, 0.827428, 0.0478492, 0.133529, \
          0.762658, 0.0776384, 0.14129, 0.886664, 0.347654, 0.00843196, \
          0.976925, 0.796339, 0.342714, 0.169307, 0.00014281, 0.900409, \
          0.846251, 0.773448, 0.214647, 0.951153, 0.676512, 0.15983], \
          [0.541131, 0.848564, 0.0246193, 0.910436, 0.645267, 0.943575, \
          0.98105, 0.500393, 0.166299, 0.723584, 0.190244, 0.285815, 0.892464, \
          0.951179, 0.691487, 0.308201, 0.104652, 0.266595, 0.904441, \
          0.0543669, 0.938301, 0.996299, 0.160286, 0.709642, 0.74511, 0.726303, \
          0.992327, 0.325052, 0.638849, 0.853715, 0.185038, 0.59402, 0.83834], \
          [0.828881, 0.515172, 0.189334, 0.36837, 0.318165, 0.0394882, \
          0.160242, 0.738831, 0.459337, 0.618784, 0.0900528, 0.176485, \
          0.195266, 0.0603371, 0.62561, 0.789911, 0.477578, 0.536344, 0.647711, \
          0.852552, 0.850087, 0.558568, 0.891803, 0.197272, 0.192976, 0.164475, \
          0.319596, 0.65066, 0.100558, 0.908424, 0.303019, 0.300355, 0.180213], \
          [0.451996, 0.865975, 0.633373, 0.783782, 0.267788, 0.622571, \
          0.507511, 0.912514, 0.731618, 0.855629, 0.847638, 0.599914, \
          0.0305685, 0.577372, 0.779523, 0.512601, 0.362865, 0.547878, \
          0.603194, 0.444419, 0.626591, 0.840922, 0.38914, 0.353191, 0.0650096, \
          0.173542, 0.615509, 0.920381, 0.29204, 0.387202, 0.195245, 0.802745, \
          0.306493], [0.473989, 0.387328, 0.112169, 0.473414, 0.110307, \
          0.444611, 0.598916, 0.619197, 0.896273, 0.769338, 0.013492, 0.742983, \
          0.783966, 0.74329, 0.566827, 0.780564, 0.675125, 0.299919, 0.900265, \
          0.991216, 0.0544971, 0.538257, 0.719562, 0.536944, 0.668761, \
          0.279333, 0.322903, 0.333724, 0.587359, 0.961897, 0.0342651, 0.16843, \
          0.627418], [0.243316, 0.199035, 0.475978, 0.0644149, 0.553477, \
          0.786537, 0.234219, 0.778276, 0.37508, 0.257621, 0.700972, 0.699155, \
          0.274507, 0.765203, 0.435808, 0.916153, 0.532233, 0.0381237, \
          0.900033, 0.176873, 0.0741992, 0.532318, 0.43112, 0.208764, 0.555612, \
          0.530045, 0.015728, 0.235306, 0.145328, 0.585243, 0.992986, 0.722389, \
          0.730683], [0.423743, 0.848841, 0.836249, 0.639022, 0.354534, \
          0.92115, 0.0732236, 0.381685, 0.586385, 0.00352369, 0.429172, \
          0.131378, 0.360736, 0.308957, 0.887067, 0.246423, 0.866243, 0.67876, \
          0.850741, 0.267307, 0.16562, 0.169409, 0.807195, 0.90028, 0.114799, \
          0.143976, 0.0529281, 0.613068, 0.564039, 0.723069, 0.312112, \
          0.881759, 0.391551]]
  return(np.array(m))

def getDefinitePositiveMatrix(d):
    a = 1.0 * np.diag(np.array(range(1,d+1)))/d
    p = getInvertibleMatrix(d)
    return(np.matmul(p,np.matmul(a,np.transpose(p))))

def getSemidefinitePositiveMatrix(d,k=3):
   if d >= k + 1 :
     a = np.diag(np.hstack([np.array(range(1,d+1-k)),np.zeros(k)])) / d
   else:
     a = 1.0 * np.diag(np.array(range(1,d+1)))/d
   p = getInvertibleMatrix(d)
   return(np.matmul(p,np.matmul(a,np.transpose(p))))

def notnull(x):
    if x == 0:
        return(0.2)
    else:
        return(x)

def writeUnaryTests(config,format):
    config.setOverwrite(False)
    # For benchmarks
    NBSAMPLES=NBA*NBB
    NBVECSAMPLES = NBB
    #
    data1=np.random.randn(NBSAMPLES)
    data1 = Tools.normalize(data1)
    if format == Tools.Q7:
       data1 = data1 / 4.0
    #
    data1C=randComplex(NBSAMPLES)
    #
    if format == Tools.Q7:
       data1C = data1C / 4.0
    #
    data2=np.random.randn(NBSAMPLES)
    data2 = Tools.normalize(data2) 
    #
    vecdata=np.random.randn(NBVECSAMPLES)
    vecdata = Tools.normalize(vecdata)
    if format == Tools.Q7:
       vecdata = vecdata / 4.0
    #
    #
    config.writeInput(1, data1,"InputA")
    config.writeInput(1, asReal(data1C),"InputAC")
    #
    config.writeInput(1, data2,"InputB")
    config.writeInput(1, vecdata,"InputVec")
    #
    # For tests
    NA=[1,2,3,4,Tools.loopnb(format,Tools.TAILONLY),
    Tools.loopnb(format,Tools.BODYONLY),
    Tools.loopnb(format,Tools.BODYANDTAIL)
    ]
    unarySizes = cartesian(NA,NA)
    #
    dims=[] 
    for (a,b) in unarySizes:
       dims.append(a)
       dims.append(b)
    # One kind of matrix shape
    config.writeInputS16(1, dims,"DimsUnary")
    #
    vals = []
    for (a,b) in unarySizes:
       ma = np.copy(data1[0:a*b]).reshape(a,b)
       mb = np.copy(data2[0:a*b]).reshape(a,b)
       r = ma + mb 
       r = list(r.reshape(a*b))
       vals = vals + r
    config.writeReference(1, vals,"RefAdd")
    #
    vals=[] 
    for (a,b) in unarySizes:
       ma = np.copy(data1[0:a*b]).reshape(a,b)
       v = np.copy(vecdata[0:b])
       r = ma.dot(v)
       r = list(r.reshape(a))
       vals = vals + r
    config.writeReference(1, vals,"RefVecMul")
    #
    vals = []
    for (a,b) in unarySizes:
       ma = np.copy(data1[0:a*b]).reshape(a,b)
       mb = np.copy(data2[0:a*b]).reshape(a,b)
       r = ma - mb 
       r = list(r.reshape(a*b))
       vals = vals + r
    config.writeReference(1, vals,"RefSub")
    #
    vals = []
    for (a,b) in unarySizes:
       ma = np.copy(data1[0:a*b]).reshape(a,b)
       r = np.transpose(ma)
       r = list(r.reshape(a*b))
       vals = vals + r
    config.writeReference(1, vals,"RefTranspose")
    #
    vals = []
    for (a,b) in unarySizes:
       ma = np.copy(data1C[0:a*b]).reshape(a,b)
       r = np.transpose(ma)
       r = list(asReal(r.reshape(a*b)))
       vals = vals + r
    config.writeReference(1, vals,"RefTransposeC")
    #
    vals = []
    for (a,b) in unarySizes:
       ma = np.copy(data1[0:a*b]).reshape(a,b)
       r = ma * 0.5
       r = list(r.reshape(a*b))
       vals = vals + r
    config.writeReference(1, vals,"RefScale")
    #
    # Current algo is not very accurate for big matrix.
    # But big matrix required to check the vectorized code.
    if format==Tools.F16:
       # Size limited for f16 because accuracy is
       # not good at all for bigger matrices
       dims=[1,2,3,4,7,8,9,15,16]
    else:
       dims=[1,2,3,4,7,8,9,15,16,17,32,33]
    #

    if format == Tools.F32 or format == Tools.F16 or format == Tools.F64:
       config.setOverwrite(True)
    vals = []
    inp=[]
    
    for d in dims:
        ma = getInvertibleMatrix(d)
        inp = inp + list(ma.reshape(d*d))
        r = numpy.linalg.inv(ma)
        vals = vals + list(r.reshape(d*d))
    #
    # Add matrix for testing null pivot condition
    ma = np.array([[0., 3.], [4., 5.]])
    inp = inp + list(ma.reshape(4))
    r = np.linalg.inv(ma)
    vals = vals + list(r.reshape(4))
    dims.append(2)
    #
    config.writeInputS16(1, dims,"DimsInvert")
    config.writeInput(1, inp,"InputInvert")
    config.writeReference(1, vals,"RefInvert")

    config.setOverwrite(False)
    # One kind of matrix shape

    # Cholesky and LDLT definite positive (DPO)
    inp=[]
    vals = []
    dvals=[] 
    llvals=[] 
    permvals=[]
    uts=[] # U
    lts=[] # L
    rndas=[] # A
    utinvs=[] # X such that UX=A
    ltinvs=[] # X such that LX=A
    cholinvs=[] # X such that MA X  = A where A positive definite
    for d in dims:
       ma = getDefinitePositiveMatrix(d)
       inp = inp + list(ma.reshape(d*d))
       # Lower triangular 
       l = scipy.linalg.cholesky(ma,lower=True)

       vals = vals + list(l.reshape(d*d))

       ll, di, perm = ldlt(ma)

       if not valid(ma,ll,di,perm):
          print("Error LDLT with positive definite !")
          sys.exit(1)

       llvals = llvals + list(ll.reshape(d*d))
       dvals = dvals + list(di.reshape(d*d))
       permvals = permvals + list(perm.reshape(d))

       a = np.random.randn(d*d)
       a = Tools.normalize(a)
       a = a.reshape(d,d)

       lt = l 
       ut = l.transpose()

       utinv = np.linalg.solve(ut,a)
       ltinv = np.linalg.solve(lt,a)
       cholinv = np.linalg.solve(ma,a)

       uts += list(ut.reshape(d*d)) 
       lts += list(lt.reshape(d*d)) 
       rndas += list(a.reshape(d*d))

       utinvs += list(utinv.reshape(d*d)) 
       ltinvs += list(ltinv.reshape(d*d))
       cholinvs += list(cholinv.reshape(d*d))



    config.writeInputS16(1, dims,"DimsCholeskyDPO")
    config.writeInput(1, inp,"InputCholeskyDPO")
    config.writeReference(1, vals,"RefCholeskyDPO")

    config.writeReference(1, llvals,"RefLDLT_LL_DPO")
    config.writeReference(1, dvals,"RefLDLT_D_DPO")
    config.writeReferenceS16(1, permvals,"RefLDLT_PERM_DPO")

    config.writeInput(1, uts,"InputUTDPO")
    config.writeInput(1, lts,"InputLTDPO")
    config.writeInput(1, rndas,"InputRNDA")

    config.writeReference(1, utinvs,"Ref_UTINV_DPO")
    config.writeReference(1, ltinvs,"Ref_LTINV_DPO")
    config.writeReference(1, cholinvs,"Ref_CHOLINV_DPO")

    r=np.array([(4,4),(8,8),(9,9),(15,15),(16,16)])
    r=r.reshape(2*5)
    config.writeParam(1, r,"ParamsCholesky")


    # Cholesky and LDLT semi definite positive (SDPO)
    dims=[1,2,3,4,7]
    inp=[]
    vals = []
    dvals=[] 
    llvals=[] 
    permvals=[]
    for d in dims:
       ma = getSemidefinitePositiveMatrix(d)
       inp = inp + list(ma.reshape(d*d))

       ll, di, perm = ldlt(ma)
       if not valid(ma,ll,di,perm):
          print("Error LDLT with positive semi definite !")
          sys.exit(1)

       llvals = llvals + list(ll.reshape(d*d))
       dvals = dvals + list(di.reshape(d*d))
       permvals = permvals + list(perm.reshape(d))


    config.writeInputS16(1, dims,"DimsCholeskySDPO")
    config.writeInput(1, inp,"InputCholeskySDPO")

    config.writeReference(1, llvals,"RefLDLT_LL_SDPO")
    config.writeReference(1, dvals,"RefLDLT_D_SDPO")
    config.writeReferenceS16(1, permvals,"RefLDLT_PERM_SDPO")

    # Lower and upper triangular
    config.setOverwrite(True)
    thedims=[]
    theltmatrix=[] 
    theutmatrix=[] 
    thevectors=[]
    theltinvs=[]
    theutinvs=[]
    nb = 0
    for matrixDim in dims:
        for cols in range(1,matrixDim):
            thedims.append((matrixDim,cols))
            nb = nb + 1
            matrix=np.random.randn(matrixDim * matrixDim).reshape(matrixDim,matrixDim)
            matrix = Tools.normalize(matrix)
            # LT
            matrixLT = np.tril(matrix)
            diagvalues=[notnull(x) for x in np.diagonal(matrixLT)]
            np.fill_diagonal(matrixLT, diagvalues)
            #UP
            matrixUT = np.triu(matrix)
            diagvalues=[notnull(x) for x in np.diagonal(matrixUT)]
            np.fill_diagonal(matrixUT, diagvalues)

            
            theltmatrix = theltmatrix + list(matrixLT.reshape(matrixDim*matrixDim))
            theutmatrix = theutmatrix + list(matrixUT.reshape(matrixDim*matrixDim))

            vector=np.random.randn(matrixDim * cols)
            vector = Tools.normalize(vector)
            vector = [notnull(x) for x in vector]
            vector = np.array(vector).reshape(matrixDim,cols)
            thevectors = thevectors + list(vector.reshape(matrixDim*cols))

            refLT=np.linalg.solve(matrixLT,vector)
            theltinvs = theltinvs + list(refLT.reshape(matrixDim*cols))

            refUT=np.linalg.solve(matrixUT,vector)
            theutinvs = theutinvs + list(refUT.reshape(matrixDim*cols))

    thedims=list(np.array(thedims).reshape(2*nb))
    config.writeInput(1, theltmatrix,"InputMatrixLTSolve")
    config.writeInput(1, theutmatrix,"InputMatrixUTSolve")
    config.writeInput(1, thevectors,"InputVectorLTSolve")
    config.writeReference(1, theltinvs,"RefLTSolve")
    config.writeReference(1, theutinvs,"RefUTSolve")
    config.writeInputS16(1, thedims,"DimsLTSolve")
    config.setOverwrite(False)


def generatePatterns():
    PATTERNBINDIR = os.path.join("Patterns","DSP","Matrix","Binary","Binary")
    PARAMBINDIR = os.path.join("Parameters","DSP","Matrix","Binary","Binary")
    
    configBinaryf64=Tools.Config(PATTERNBINDIR,PARAMBINDIR,"f64")
    configBinaryf32=Tools.Config(PATTERNBINDIR,PARAMBINDIR,"f32")
    configBinaryf16=Tools.Config(PATTERNBINDIR,PARAMBINDIR,"f16")
    configBinaryq31=Tools.Config(PATTERNBINDIR,PARAMBINDIR,"q31")
    configBinaryq15=Tools.Config(PATTERNBINDIR,PARAMBINDIR,"q15")
    configBinaryq7=Tools.Config(PATTERNBINDIR,PARAMBINDIR,"q7")

    configBinaryf64.setOverwrite(False)
    configBinaryf32.setOverwrite(False)
    configBinaryf16.setOverwrite(False)
    configBinaryq31.setOverwrite(False)
    configBinaryq15.setOverwrite(False)
    configBinaryq7.setOverwrite(False)

    
    writeBinaryTests(configBinaryf64,Tools.F32)
    writeBinaryTests(configBinaryf32,Tools.F32)
    writeBinaryTests(configBinaryf16,Tools.F16)
    writeBinaryTests(configBinaryq31,Tools.Q31)
    writeBinaryTests(configBinaryq15,Tools.Q15)
    writeBinaryTests(configBinaryq7,Tools.Q7)
    
    PATTERNUNDIR = os.path.join("Patterns","DSP","Matrix","Unary","Unary")
    PARAMUNDIR = os.path.join("Parameters","DSP","Matrix","Unary","Unary")
    
    configUnaryf64=Tools.Config(PATTERNUNDIR,PARAMUNDIR,"f64")
    configUnaryf32=Tools.Config(PATTERNUNDIR,PARAMUNDIR,"f32")
    configUnaryf16=Tools.Config(PATTERNUNDIR,PARAMUNDIR,"f16")
    configUnaryq31=Tools.Config(PATTERNUNDIR,PARAMUNDIR,"q31")
    configUnaryq15=Tools.Config(PATTERNUNDIR,PARAMUNDIR,"q15")
    configUnaryq7=Tools.Config(PATTERNUNDIR,PARAMUNDIR,"q7")
    
    configUnaryf64.setOverwrite(False)
    configUnaryf32.setOverwrite(False)
    configUnaryf16.setOverwrite(False)
    configUnaryq31.setOverwrite(False)
    configUnaryq15.setOverwrite(False)
    configUnaryq7.setOverwrite(False)
    
    writeUnaryTests(configUnaryf64,Tools.F64)
    writeUnaryTests(configUnaryf32,Tools.F32)
    writeUnaryTests(configUnaryf16,Tools.F16)
    writeUnaryTests(configUnaryq31,Tools.Q31)
    writeUnaryTests(configUnaryq31,Tools.Q31)
    writeUnaryTests(configUnaryq15,Tools.Q15)
    writeUnaryTests(configUnaryq7,Tools.Q7)

if __name__ == '__main__':
  generatePatterns()